import {useUserStore} from "@/store/modules/user";
import {Directive, DirectiveBinding} from "vue";
import {Role} from "@/utils/enum-type";
// 规则类型
export type PermsType = string | string[] | string[][];

/**
 * 按钮权限(规则如下)
 *   // 参考 https://www.npmjs.com/package/express-jwt-permissions
 *   // 'read' Required: "read"
 *  // ['read', 'write']  Required: "read" AND "write"
 *  //  [ ['admin'], ['read', 'write']]  Required: "admin" OR ("read" AND "write")
 */
export const hasPerm: Directive = {
    mounted(el: HTMLElement, binding: DirectiveBinding) {
        // 「超级管理员」拥有所有的按钮权限
        const {roles, perms} = useUserStore();
        if (roles.includes(Role.Root)) {
            return true;
        }
        // 「其他角色」按钮权限校验
        // 有值 有权限 放行
        // 有值 无权限 移除节点
        // 无知 放行
        const {value} = binding;
        if (value) {
            // 检查权限,如果没有,就移除这个元素
            if (!checkPerms(value, perms)) {
                el.parentNode && el.parentNode.removeChild(el);
            }
        }
    },
};

/**
 * 角色权限
 */
export const hasRole: Directive = {
    mounted(el: HTMLElement, binding: DirectiveBinding) {
        // 「超级管理员」拥有所有的按钮权限
        const {roles} = useUserStore();
        if (roles.includes(Role.Root)) {
            return true;
        }
        const {value} = binding;
        if (value) {
            if (!checkPerms(value, roles)) {
                el.parentNode && el.parentNode.removeChild(el);
            }
        } else {
            throw new Error("需要角色! 比如 v-role=\"['admin','test']\"");
        }
    },
};

/**
 * 检查规则
 * @param requiredPerms
 * @param userPerms
 */
function checkPerms(requiredPerms: PermsType, userPerms: string[]): boolean {
    try {
        // 比如 'read'
        if (typeof requiredPerms === 'string') {
            return userPerms.includes(requiredPerms);
        } else if (Array.isArray(requiredPerms) && requiredPerms.length > 0) {
            // 比如 ['read', 'write']
            if (typeof requiredPerms[0] === 'string') {
                return (requiredPerms as string[]).every((perm: string) =>
                    userPerms.includes(perm),
                );
            } else {
                // 比如 [ ['admin'], ['read', 'write']]
                return (requiredPerms as string[][]).some((perm: string[]) =>
                    checkPerms(perm, userPerms),
                );
            }
        } else {
            return false;
        }
    } catch {
        console.error('传入的数据有问题,请仔细检查,传入的数据为:', requiredPerms)
        return false;
    }

}
